package org.speed.ddd;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class CallResult<T> {
	
	private int code = 200;
	private String msg;
	private T data;
	private long timestamp;
	private Throwable exception;
	private Map<String, Object> ext = new HashMap<>();
	
	@SuppressWarnings("rawtypes")
	public static CallResult SUCC = CallResult.toSucc();
	
	@SuppressWarnings("rawtypes")
	public static CallResult FAIL = CallResult.toFail();
	
	public CallResult(int code,String msg,T data,Throwable exception) {
		this.code = code;
		this.msg = msg;
		this.data = data;
		this.exception = exception;
		this.timestamp = System.currentTimeMillis();
	}
	
	public CallResult(int code,String msg,Throwable ex) {
		this(code,msg,null,ex);	
	}
	
	public boolean isSucc() {
		return 200 == code ? true : false;
	}
	
	public T getData() {
		return data;
	}
	
	public void addExt(String key,Object value) {
		ext.putIfAbsent(key, value);
	}
	
	public void addExt(Map<String, Object> map) {
		Set<String> keySet = map.keySet();
		Iterator<String> iterator = keySet.iterator();
		while(iterator.hasNext()) {
			String key = iterator.next();
			ext.putIfAbsent(key, map.get(key));
		}
	}
	
	public static<T> CallResult<T> toSucc() {
		return new CallResult<T>(200,null,null,null);
	}
	
	public static<T> CallResult<T> toSucc(T data) {
		return new CallResult<T>(200,null,data,null);
	}
	
	public static<T> CallResult<T> toFail() {
		return new CallResult<T>(500,null,null,null);
	}
	
	public static<T> CallResult<T> toFail(String msg,Throwable ex) {
		return new CallResult<T>(500,msg,null,ex);
	}
	
	@Override
	public String toString() {
		return "CallResult:[code=" + code + ", msg=" + msg + ", data=" + data + ", timestamp=" + timestamp + ", exception=" + exception + ", ext=" + ext + "]";
	}

	public static void main(String[] args) {
		CallResult result1 = CallResult.SUCC;
		System.out.println(result1);
		
		CallResult<List<String>> result2 = CallResult.toSucc(Arrays.asList(new String[] {"1001","1002","1003"}));
		System.out.println(result2);
		
		CallResult result3 = CallResult.toFail("参数错误", new RuntimeException("call service fail"));
		System.out.println(result3);
	}
	

}
